package com.xxkj.nmip.js;

import android.Manifest;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.CountDownTimer;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.webkit.JavascriptInterface;


import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;

import com.xxkj.nmip.dialog.UpDateDialog;
import com.xxkj.nmip.page.BaseActivity;
import com.xxkj.nmip.page.MainActivity;
import com.xxkj.nmip.R;
import com.xxkj.nmip.bean.JsResBean;
import com.xxkj.nmip.canstant.BaseCanstant;
import com.xxkj.nmip.dialog.InputDialog;
import com.xxkj.nmip.utils.AppUtils;
import com.xxkj.nmip.utils.AudioRecoderUtils;
import com.xxkj.nmip.utils.DeviceIdUtil;
import com.xxkj.nmip.utils.ImageBase64;
import com.xxkj.nmip.utils.SPUtils;
import com.xxkj.nmip.utils.ToastUtils;
import com.xxkj.nmip.utils.ZpImageUtils;

import wendu.dsbridge.CompletionHandler;

/**
 * Created by du on 16/12/31.
 */

public class JsApi {
    private Context context;
    private JsResBean jsResBean;
    private Handler handler;
    private File mTakePhotoFile;
    private File mFileFromCamera;
    private final int REQ_CHOOSE = 50;
    private final int REQUEST_TAKE_CODE = 51;
    private final int REQUEST_TAKE_RECORD = 52;
    public static final int WRITE_EXTERNAL_STORAGE_AND_CAMERA_REQUEST_CODE = 3;
    long start = 0 ;
    long finish =0;
    long timeElapsed = 0;

    public JsApi(Context context) {
        this.context = context;
        handler = new Handler();
    }

    @JavascriptInterface
    public String testSyn(Object params) {

        JSONObject data = ((JSONObject) params);
        String key = "";
        try {
            key = data.getString("name");
        } catch (Exception e) {
        }
        try {
            if (BaseCanstant.getUserToken.equals(key)) {
                return getDeviceInfo();
            } else if (BaseCanstant.openWebview.equals(key)) {
                return openWebview(data);
            } else if (BaseCanstant.changeh5url.equals(key)) {
                return changeUrl();
            } else if (BaseCanstant.closeWebview.equals(key)) {
                return closeWebview();
            }else if (BaseCanstant.closeApp.equals(key)) {
                return closeApp();
            }else {
                return new JsResBean(JsCodeType.NOT_METHOD, "").toString();
            }
        } catch (Exception e) {
            return new JsResBean(JsCodeType.FAIL, "程序内部异常,请检查参数是否合法，或联系管理员", "").toString();
        }
    }


    @JavascriptInterface
    public void testAsyn(final Object params, final CompletionHandler<String> jsHandler) {
        new Thread() {
            @Override
            public void run() {
                super.run();
//                JSONObject data = ((JSONObject) params);
                String key =((String) params);
//                try {
//                    key = data.getJSONObject("data").getString("name");
//                } catch (Exception e) {
//                }

                try {
                    if (BaseCanstant.getPicture.equals(key)) {
                        getPicture(jsHandler);
                    } else if (BaseCanstant.getCamera.equals(key)) {
                        getCamera(jsHandler);
                    } else if (BaseCanstant.savePicture.equals(key)) {
//                        savePicture(jsHandler, data);
                    } else if (BaseCanstant.getAudioRecord.equals(key)) {
                        getRecord(jsHandler);
                    } else if (BaseCanstant.startRecord.equals(key)) {
                        startRecord(jsHandler);
                    } else if (BaseCanstant.stopRecord.equals(key)) {
                        stopRecord(jsHandler);
                    }  else if (BaseCanstant.toLogin.equals(key)) {
                        toLogin(jsHandler, key);
                    }else {
                        jsResBean = new JsResBean(JsCodeType.NOT_METHOD, "not method ", "");
                        sendMsg(jsHandler, jsResBean);
                    }
                } catch (Exception e) {
                    jsResBean = new JsResBean(JsCodeType.FAIL, "数据异常", e != null ? e.getMessage() : "数据异常");
                    sendMsg(jsHandler, jsResBean);
                }
            }
        }.start();
    }


    @JavascriptInterface
    public String testNoArgSyn(Object arg) throws JSONException {
        return "testNoArgSyn called [ syn call]";
    }

    @JavascriptInterface
    public void testNoArgAsyn(Object arg, CompletionHandler<String> handler) {
        handler.complete("testNoArgAsyn   called [ asyn call]");
    }


    //@JavascriptInterface
    //without @JavascriptInterface annotation can't be called
    public String testNever(Object arg) throws JSONException {
        JSONObject jsonObject = (JSONObject) arg;
        return jsonObject.getString("msg") + "[ never call]";
    }

    @JavascriptInterface
    public void callProgress(Object args, final CompletionHandler<Integer> handler) {

        new CountDownTimer(11000, 1000) {
            int i = 10;

            @Override
            public void onTick(long millisUntilFinished) {
                //setProgressData can be called many times util complete be called.
                handler.setProgressData((i--));

            }

            @Override
            public void onFinish() {
                //complete the js invocation with data; handler will be invalid when complete is called
                handler.complete(0);

            }
        }.start();
    }

    /**
     * 获取设备相关信息
     *
     * @return
     * @throws Exception
     */
    private String getDeviceInfo() throws Exception {
        HashMap map = new HashMap();
        map.put("systemVersion", AppUtils.getSystemVersion());// 系统版本
        map.put("imei", AppUtils.getIMEI(context));// 设备的国际移动设备身份码
        map.put("imsi", AppUtils.getIMSI(context));// 设备的国际移动用户识别码
        map.put("model", AppUtils.getMobileModel()); // 设备的型号
        map.put("vendor", AppUtils.getDeviceBrand()); // 设备的生产厂商
        map.put("uuid", AppUtils.getIMEI(context));// 设备的唯一标识
        jsResBean = new JsResBean(JsCodeType.SUCCESS, map);
        return jsResBean.toString();
    }

    private void sendMsg(final CompletionHandler<String> jsHandler, final JsResBean jsResBean) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                jsHandler.complete(jsResBean.toString());
            }
        });
    }

    /**
     * 从相册获取图片
     */
    private void getPicture(final CompletionHandler<String> jsHandler) throws Exception {
        ((BaseActivity) (context)).runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (context instanceof MainActivity) {
                    ((BaseActivity) (context)).setOnactivityRelsultLister(new OnactivityRelsultLister() {
                        @Override
                        public void onActivityResult(int requestCode, int resultCode, Intent data) {
                            HashMap hashMap = new HashMap();
                            switch (requestCode) {
                                case REQ_CHOOSE:
                                    try {
                                        String imageStr = "";
                                        if (data != null) {
                                            String dataString = data.getDataString();
                                            if (dataString != null) {
                                                Uri uri = Uri.parse(dataString);
                                                File imgFile = new File(getRealPathFromURI(uri));
                                                imageStr = "data:image/jpeg;base64," + ImageBase64.fileToBase64(imgFile);
                                            }
                                        }
                                        hashMap.put("url", imageStr);
                                        if (TextUtils.isEmpty(imageStr)) {
                                            jsResBean = new JsResBean(JsCodeType.FAIL, "获取失败，或用户已取消", hashMap);
                                        } else {
                                            jsResBean = new JsResBean(JsCodeType.SUCCESS, hashMap);
                                        }
                                        sendMsg(jsHandler, jsResBean);
                                    } catch (Exception e) {
                                        jsResBean = new JsResBean(JsCodeType.FAIL, "获取相片异常", hashMap);
                                        sendMsg(jsHandler, jsResBean);
                                    }
                                    break;
                            }
                        }
                    });
                    selectImage();
                }
            }
        });
    }


    /**
     * 根据uri获取真实路径
     *
     * @param contentUri
     * @return
     */
    private String getRealPathFromURI(Uri contentUri) {
        String res = null;
        String[] proj = {MediaStore.Images.Media.DATA};
        Cursor cursor = ((Activity) context).getContentResolver().query(contentUri, proj, null, null, null);
        if (cursor.moveToFirst()) {
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            res = cursor.getString(column_index);
        }
        cursor.close();
        return res;
    }

    /**
     * 选择照片
     */
    private void selectImage() {
        Intent intent;
        if (Build.VERSION.SDK_INT < 19) {
            intent = new Intent(Intent.ACTION_GET_CONTENT);
            intent.setType("image/*");
            ((Activity) context).startActivityForResult(intent, REQ_CHOOSE);
        } else {
            intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            Intent wrapperIntent = Intent.createChooser(intent, null);
            ((Activity) context).startActivityForResult(wrapperIntent, REQ_CHOOSE);
        }
    }

    /**
     * 拍照获取图片
     *
     * @param jsHandler
     */
    private void getCamera(final CompletionHandler<String> jsHandler) throws Exception {
        if (!((BaseActivity) (context)).getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) {
            ((BaseActivity) (context)).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    ToastUtils.showCenter(context, "设备无摄像头");
                }
            });
            return;
        }

        if (!checkStorageAndCameraPermission()) {
            jsResBean = new JsResBean(JsCodeType.FAIL, "无相关权限", new HashMap<>());
            sendMsg(jsHandler, jsResBean);
            return;
        }

        ((BaseActivity) (context)).setOnactivityRelsultLister(new OnactivityRelsultLister() {
            @Override
            public void onActivityResult(int requestCode, final int resultCode, Intent data) {
                final HashMap hashMap = new HashMap();
                switch (requestCode) {
                    case REQUEST_TAKE_CODE://拍照回调
                        try {
                            new Thread() {
                                @Override
                                public void run() {
                                    super.run();
                                    String imageStr = "";
                                    if (resultCode == Activity.RESULT_OK) {
                                        if (mFileFromCamera != null) {
                                            String filePath = mTakePhotoFile.getAbsolutePath();
                                            // 压缩图片到指定大小
                                            File imgFile = ZpImageUtils.compressImage(context, filePath, 1024, 1024, 300);
//                                                    File imgFile = new File(filePath);
                                            Uri localUri = Uri.fromFile(imgFile);
                                            Intent localIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, localUri);
                                            ((BaseActivity) (context)).sendBroadcast(localIntent);
                                            Uri result = Uri.fromFile(imgFile);
                                            imageStr = "data:image/jpeg;base64," + ImageBase64.getImageStr(imgFile.getAbsolutePath());
//                                            imageStr = imgFile.getAbsolutePath();
                                        }
                                    }
                                    if (TextUtils.isEmpty(imageStr)) {
                                        jsResBean = new JsResBean(JsCodeType.FAIL, "获取失败，或用户已取消", hashMap);
                                    } else {
                                        hashMap.put("url", imageStr);
                                        jsResBean = new JsResBean(JsCodeType.SUCCESS, hashMap);
                                    }
                                    sendMsg(jsHandler, jsResBean);
                                }
                            }.start();
                        } catch (Exception e) {
                            jsResBean = new JsResBean(JsCodeType.FAIL, "获取相片异常", hashMap);
                            sendMsg(jsHandler, jsResBean);
                        }
                        break;
                }
            }
        });

        String filePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath();
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        mFileFromCamera = new File(filePath, System.nanoTime() + ".jpg");
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTakePhotoFile));
            ((BaseActivity) (context)).startActivityForResult(intent, REQUEST_TAKE_CODE);
        } else {
            try {
                mTakePhotoFile = File.createTempFile("Zp" + System.nanoTime(), ".jpg", new File(filePath));
                Uri contentUri = FileProvider.getUriForFile(context,
                        ((BaseActivity) (context)).getPackageName() + ".provider", mTakePhotoFile);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, contentUri);
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                ((BaseActivity) (context)).startActivityForResult(intent, REQUEST_TAKE_CODE);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void startRecord (final CompletionHandler<String> jsHandler) throws Exception {
        ((MainActivity) (context)).runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (context instanceof MainActivity) {
                    AudioRecoderUtils.getInstance().startRecord();
                     start = System.currentTimeMillis();

                    HashMap hashMap = new HashMap();
                    hashMap.put("recordflag", "录音开始了");
                    jsResBean = new JsResBean(JsCodeType.SUCCESS, hashMap);
                    sendMsg(jsHandler, jsResBean);
                }

            }
        });
//        AudioRecoderUtils.getInstance().startRecord();
//        HashMap hashMap = new HashMap();
//        hashMap.put("url", "录音开始了");
//        jsResBean = new JsResBean(JsCodeType.SUCCESS, hashMap);
//        sendMsg(jsHandler, jsResBean);
    }
    private void stopRecord (final CompletionHandler<String> jsHandler) throws Exception {
        ((MainActivity) (context)).runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (context instanceof MainActivity) {
                    AudioRecoderUtils.getInstance().stopRecord();

                    HashMap hashMap = new HashMap();
                    try {
                        finish = System.currentTimeMillis();
                        String recordString = AudioRecoderUtils.getInstance().getRecordString();

                         if (finish>0&& start>0){
                              timeElapsed = finish - start;
                         }

                        hashMap.put("recordusetime", String.valueOf(timeElapsed));
                        hashMap.put("url", recordString);
                        if (TextUtils.isEmpty(recordString)) {
                            jsResBean = new JsResBean(JsCodeType.FAIL, "获取失败，或用户已取消", hashMap);
                        } else {
                            jsResBean = new JsResBean(JsCodeType.SUCCESS, hashMap);
                        }
                        sendMsg(jsHandler, jsResBean);
                    } catch (Exception e) {
                        jsResBean = new JsResBean(JsCodeType.FAIL, "获取录音异常", hashMap);
                        sendMsg(jsHandler, jsResBean);
                    }
                }
            }
        });
//            AudioRecoderUtils.getInstance().stopRecord();
//
//            HashMap hashMap = new HashMap();
//            try {
//                String recordString = AudioRecoderUtils.getInstance().getRecordString();
//
//                hashMap.put("url", recordString);
//                if (TextUtils.isEmpty(recordString)) {
//                    jsResBean = new JsResBean(JsCodeType.FAIL, "获取失败，或用户已取消", hashMap);
//                } else {
//                    jsResBean = new JsResBean(JsCodeType.SUCCESS, hashMap);
//                }
//                sendMsg(jsHandler, jsResBean);
//            } catch (Exception e) {
//                jsResBean = new JsResBean(JsCodeType.FAIL, "获取录音异常", hashMap);
//                sendMsg(jsHandler, jsResBean);
//            }
    }
    private void getRecord (final CompletionHandler<String> jsHandler) throws Exception {
        ((BaseActivity) (context)).runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (context instanceof MainActivity) {
                    ((BaseActivity) (context)).setOnactivityRelsultLister(new OnactivityRelsultLister() {
                        @Override
                        public void onActivityResult(int requestCode, int resultCode, Intent data) {
                            HashMap hashMap = new HashMap();
                            switch (requestCode) {
                                case REQUEST_TAKE_RECORD:
                                    try {
                                        String imageStr = "";
                                        if (data != null) {
                                            String dataString = data.getDataString();
                                            if (dataString != null) {
                                                Uri uri = Uri.parse(dataString);
                                                File imgFile = new File(getRealPathFromURI(uri));
                                                imageStr =  ImageBase64.fileToBase64(imgFile);
                                            }
                                        }
                                        hashMap.put("url", imageStr);
                                        if (TextUtils.isEmpty(imageStr)) {
                                            jsResBean = new JsResBean(JsCodeType.FAIL, "获取失败，或用户已取消", hashMap);
                                        } else {
                                            jsResBean = new JsResBean(JsCodeType.SUCCESS, hashMap);
                                        }
                                        sendMsg(jsHandler, jsResBean);
                                    } catch (Exception e) {
                                        jsResBean = new JsResBean(JsCodeType.FAIL, "获取录音异常", hashMap);
                                        sendMsg(jsHandler, jsResBean);
                                    }
                                    break;
                            }
                        }
                    });
                    selectRecord();
                }
            }
        });
    }

    private void selectRecord() {
        //设置intent的属性为录音设置
        Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
        ((Activity) context).startActivityForResult(intent, REQUEST_TAKE_RECORD);
    }

    private String changeUrl( ) {

        new InputDialog(context, R.style.dialog, "", new InputDialog.OnCloseListener() {
            @Override
            public void onClick(Dialog dialog, boolean confirm,String content) {
                if (confirm) {

                    if (!TextUtils.isEmpty(content)) {
                        final String u = content;
                        ((BaseActivity) context).runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    Intent intent = new Intent();
                                    intent.setClass(context, MainActivity.class);
                                    intent.putExtra("baseurl_js", u);
                                    context.startActivity(intent);
                                    jsResBean = new JsResBean(JsCodeType.SUCCESS, "打开成功", "");
                                } catch (Exception e) {
                                }
                            }
                        });
                    } else {
                        jsResBean = new JsResBean(JsCodeType.PARAMETER_ERROR, "URL不能为空", "");
                    }

                }
                dialog.dismiss();
            }
        }).setTitle("确认更改地址?").show();

        return jsResBean.toString();
    }

    private String openWebview(JSONObject p) {
        String url = "";
        try {
            url = p.getJSONObject("data").getString("url");
        } catch (Exception e) {
            jsResBean = new JsResBean(JsCodeType.FAIL, "打开失败", "");
        }
        if (!TextUtils.isEmpty(url)) {
            final String u = url;
            ((BaseActivity) context).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Intent intent = new Intent();
                        intent.setClass(context, MainActivity.class);
                        intent.putExtra("baseurl_js", u);
                        context.startActivity(intent);
                        jsResBean = new JsResBean(JsCodeType.SUCCESS, "打开成功", "");
                    } catch (Exception e) {
                    }
                }
            });
        } else {
            jsResBean = new JsResBean(JsCodeType.PARAMETER_ERROR, "URL不能为空", "");
        }
        return jsResBean.toString();
    }

    /**
     * 关闭当前页面
     *
     * @return
     * @throws Exception
     */
    private String closeWebview() throws Exception {
        ((BaseActivity) context).finish();
        jsResBean = new JsResBean(JsCodeType.SUCCESS, "关闭成功", "");
        return jsResBean.toString();
    }

    /**
     * 关闭当前app
     *
     * @return
     * @throws Exception
     */
    private String closeApp() throws Exception {

        ((BaseActivity) context).finish();
        System.exit(0);
        jsResBean = new JsResBean(JsCodeType.SUCCESS, "关闭成功", "");




        return jsResBean.toString();
    }


    private void toLogin(final CompletionHandler<String> jsHandler, String data) throws Exception {
        ((BaseActivity) context).setOnactivityRestartLister(new OnactivityRestartLister() {
            @Override
            public void onActivityRestart() {
                HashMap map = new HashMap();
                jsResBean = new JsResBean(JsCodeType.SUCCESS, map);
                sendMsg(jsHandler, jsResBean);
            }
        });
        ((BaseActivity) context).finish();
        ((BaseActivity) context).runOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {
                    Intent intent = new Intent(context, MainActivity.class);
                    context.startActivity(intent);
                } catch (Exception e) {
                }
            }
        });

    }
    /**
     * 检查存储权限 和 相机权限
     *
     * @return true, 已经获取权限;false,没有权限,尝试获取
     */
    private boolean checkStorageAndCameraPermission() {
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            //申请WRITE_EXTERNAL_STORAGE权限
            ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA,},
                    WRITE_EXTERNAL_STORAGE_AND_CAMERA_REQUEST_CODE);
            return false;
        } else {
            return true;
        }
    }

    public interface OnactivityRelsultLister {
        public void onActivityResult(int requestCode, int resultCode, Intent data);
    }

    public interface OnactivityRestartLister {
        public void onActivityRestart();
    }

    /**
     * js调用获取版本号
     * @return
     */
    @JavascriptInterface
    public String getVersion() {
        return AppUtils.getVerName(context);
    }

    /**
     * js调用开始下载安装包
     * @param url
     */
    @JavascriptInterface
    public void uploadNewAPK(String url){
        new UpDateDialog(context,url).showPopupWindow();
    }
    /**
     * js调用开始获取设备唯一id
     * @return 设备唯一id
     */
    @JavascriptInterface
    public String getDeviceUUID(){
        return DeviceIdUtil.getDeviceId(context);
    }
    /**
     * js调用开始获取设备系统名
     * @return 设备系统名
     */
    @JavascriptInterface
    public String getSystemName(){
        return "Android";
    }
    /**
     * js调用往壳上存储想存的数据，只能传String，如果是对象，可以转成json字符串后存储，获取后自行解析成对象
     */
    @JavascriptInterface
    public void saveData(String key,String value){
         SPUtils.put(context,key,value);
    }
    /**
     * js调用开始获取存在壳上的数据
     * @return String
     */
    @JavascriptInterface
    public String getData(String key){
        return SPUtils.get(context,key);
    }
}